import path from 'path';
import fs from 'fs';
import { PathMappingConfigService, type PathMappingRule } from './PathMappingConfigService.js';

/**
 * 路径映射服务
 * 用于在Docker容器中将宿主机路径映射到容器内路径
 */
export class PathMappingService {
  private static readonly DOCKER_PROJECT_ROOT = '/projects';
  
  // 保留默认映射作为后备选项
  private static readonly FALLBACK_HOST_ROOTS = [
    '/Users',     // macOS
    '/home',      // Linux
    'C:\\',       // Windows C盘
    'D:\\',       // Windows D盘
    'E:\\',       // Windows E盘
    'F:\\',       // Windows F盘
  ];

  /**
   * 检测是否在Docker容器中运行
   */
  static isRunningInDocker(): boolean {
    try {
      // 检查是否存在Docker特有的文件
      return fs.existsSync('/.dockerenv') || 
             fs.existsSync('/proc/1/cgroup') && 
             fs.readFileSync('/proc/1/cgroup', 'utf8').includes('docker');
    } catch {
      return false;
    }
  }

  /**
   * 将宿主机路径映射到Docker容器内路径
   * @param hostPath 宿主机路径
   * @returns 容器内路径
   */
  static mapHostPathToContainer(hostPath: string): string {
    if (!this.isRunningInDocker()) {
      return hostPath; // 非Docker环境，直接返回原路径
    }

    // 标准化路径分隔符
    const normalizedPath = hostPath.replace(/\\/g, '/');
    
    // 检查是否已经是容器内路径
    if (normalizedPath.startsWith(this.DOCKER_PROJECT_ROOT)) {
      return normalizedPath;
    }

    // 获取配置的映射规则
    const config = PathMappingConfigService.loadConfig();
    const enabledMappings = PathMappingConfigService.getEnabledMappings();
    
    // 首先尝试自定义映射规则（按最长匹配优先）
    const sortedMappings = enabledMappings.sort((a, b) => b.hostPath.length - a.hostPath.length);
    
    for (const mapping of sortedMappings) {
      const normalizedHostPath = mapping.hostPath.replace(/\\/g, '/');
      if (normalizedPath.startsWith(normalizedHostPath)) {
        // 提取相对路径部分
        const relativePath = normalizedPath.substring(normalizedHostPath.length);
        // 移除开头的斜杠
        const cleanRelativePath = relativePath.startsWith('/') ? relativePath.substring(1) : relativePath;
        
        let containerPath: string;
        if (cleanRelativePath) {
          // 如果有相对路径，则映射到容器路径下
          // 保持完整的相对路径结构
          containerPath = path.posix.join(mapping.containerPath, cleanRelativePath);
        } else {
          // 如果没有相对路径，直接使用容器路径
          containerPath = mapping.containerPath;
        }
        
        if (config.settings.logMappings) {
          console.log(`[PathMapping] 自定义映射: ${hostPath} -> ${containerPath}`);
        }
        return containerPath;
      }
    }

    // 如果自定义映射失败，尝试后备映射
    for (const hostRoot of this.FALLBACK_HOST_ROOTS) {
      const normalizedHostRoot = hostRoot.replace(/\\/g, '/');
      if (normalizedPath.startsWith(normalizedHostRoot)) {
        // 提取相对路径部分
        const relativePath = normalizedPath.substring(normalizedHostRoot.length);
        const cleanRelativePath = relativePath.startsWith('/') ? relativePath.substring(1) : relativePath;
        
        const pathParts = cleanRelativePath.split('/').filter(part => part.length > 0);
        if (pathParts.length > 0) {
          const projectName = pathParts[pathParts.length - 1];
          const containerPath = path.posix.join(this.DOCKER_PROJECT_ROOT, projectName);
          if (config.settings.logMappings) {
            console.log(`[PathMapping] 后备映射: ${hostPath} -> ${containerPath}`);
          }
          return containerPath;
        }
      }
    }

    // 如果无法映射，尝试直接映射到/projects下
    const pathParts = normalizedPath.split('/').filter(part => part.length > 0);
    if (pathParts.length > 0) {
      const projectName = pathParts[pathParts.length - 1];
      const projectPath = path.posix.join(this.DOCKER_PROJECT_ROOT, projectName);
      if (config.settings.logMappings) {
        console.log(`[PathMapping] 默认映射: ${hostPath} -> ${projectPath}`);
      }
      return projectPath;
    }

    return hostPath; // 无法映射时返回原路径
  }

  /**
   * 验证映射后的路径是否存在
   * @param mappedPath 映射后的路径
   * @returns 路径是否存在
   */
  static validateMappedPath(mappedPath: string): boolean {
    try {
      return fs.existsSync(mappedPath);
    } catch {
      return false;
    }
  }

  /**
   * 获取路径映射建议
   * @param hostPath 宿主机路径
   * @returns 映射建议信息
   */
  static getPathMappingSuggestion(hostPath: string): {
    mappedPath: string;
    isValid: boolean;
    suggestion?: string;
  } {
    const mappedPath = this.mapHostPathToContainer(hostPath);
    const isValid = this.validateMappedPath(mappedPath);
    
    let suggestion: string | undefined;
    
    if (!isValid && this.isRunningInDocker()) {
      suggestion = `路径映射失败。请确保在docker-compose.yml中添加了正确的卷映射：\n` +
                  `volumes:\n` +
                  `  - "${hostPath}:${mappedPath}:ro"\n` +
                  `或使用通用映射：\n` +
                  `  - "/path/to/your/projects:${this.DOCKER_PROJECT_ROOT}:ro"`;
    }
    
    return {
      mappedPath,
      isValid,
      suggestion
    };
  }

  /**
   * 批量映射项目路径
   * @param projects 项目列表
   * @returns 映射后的项目列表
   */
  static mapProjectPaths<T extends { path: string }>(projects: T[]): T[] {
    if (!this.isRunningInDocker()) {
      return projects; // 非Docker环境，直接返回
    }

    return projects.map(project => ({
      ...project,
      path: this.mapHostPathToContainer(project.path)
    }));
  }

  /**
   * 获取Docker环境信息
   */
  static getDockerInfo(): {
    isDocker: boolean;
    projectRoot: string;
    supportedHostRoots: string[];
    customMappings: PathMappingRule[];
    config: any;
  } {
    const config = PathMappingConfigService.loadConfig();
    const enabledMappings = PathMappingConfigService.getEnabledMappings();
    
    return {
      isDocker: this.isRunningInDocker(),
      projectRoot: this.DOCKER_PROJECT_ROOT,
      supportedHostRoots: this.FALLBACK_HOST_ROOTS,
      customMappings: enabledMappings,
      config: config
    };
  }

  /**
   * 添加自定义路径映射
   */
  static addCustomMapping(hostPath: string, containerPath: string, description?: string): void {
    PathMappingConfigService.addCustomMapping({
      hostPath,
      containerPath: containerPath || this.DOCKER_PROJECT_ROOT,
      description: description || `自定义映射: ${hostPath}`
    });
  }

  /**
   * 删除自定义路径映射
   */
  static removeCustomMapping(hostPath: string): boolean {
    return PathMappingConfigService.removeCustomMapping(hostPath);
  }

  /**
   * 获取所有映射规则
   */
  static getAllMappings(): PathMappingRule[] {
    return PathMappingConfigService.getEnabledMappings();
  }

  /**
   * 更新映射设置
   */
  static updateMappingSettings(settings: any): void {
    PathMappingConfigService.updateSettings(settings);
  }
}